﻿using System;
using System.Collections.Generic;
using System.Text;

namespace RSEngine.Core
{
    static public class HierarchyHelper
    {

        #region FindAll

        static public List<T> FindAll<T>(Scene scene, RSType type) where T : RSBase
        {
            List<T> result = new List<T>();
            
            foreach (Layer layer in scene.Layers)
                if(type == RSType.LightSource)
                {
                    FindLightSource<T>(result, layer);
                    break;
                }
                else if (type == RSType.Geometry || type == RSType.MeshGeometry)
                {
                    FindGeometry<T>(result, layer);
                    break;
                }

            return result;
        }

        #endregion

        #region FindLightSource

        static private void FindLightSource<T>(List<T> result, Layer layer) where T : RSBase
        {
            foreach (LightSource source in layer.Lights)
                result.Add(source as T);

            foreach (Node node in layer.Nodes)
                FindLightSource<T>(result, node);
        }

        static private void FindLightSource<T>(List<T> result, Node node) where T : RSBase
        {
            foreach (LightSource source in node.Lights)
                result.Add(source as T);

            foreach (Node child in node.Children)
                FindLightSource<T>(result, child);
        }

        #endregion

        #region FindGeometry

        static private void FindGeometry<T>(List<T> result, Layer layer) where T : RSBase
        {
            foreach (Node node in layer.Nodes)
                FindGeometry<T>(result, node);
        }

        static private void FindGeometry<T>(List<T> result, Node node) where T : RSBase
        {
            foreach (Node child in node.Children)
                FindGeometry<T>(result, child);

            foreach (Geometry geometry in node.Geometries)
            {
                result.Add(geometry as T);
                FindGeometry<T>(result, geometry);
            }
        }

        static private void FindGeometry<T>(List<T> result, Geometry geometry) where T : RSBase
        {
            foreach (Geometry child in geometry.Children)
            {
                result.Add(child as T);
                FindGeometry<T>(result, child);
            }
        }

        #endregion

    }
}
